package org.brisling.mobile.config;

import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

import org.springframework.security.crypto.codec.Base64;

public class AESConfig {

	private static AESConfig a = null;
	
	//缓存密钥
	private static Map<String,Key> initMap = new HashMap<String,Key>();
	
	private AESConfig(){}
	
	public static AESConfig getInstance(){
		if(a==null){
			a = new AESConfig();
			initKeys(initMap,100);
		}
		return a;
	}
	
	/*
	 * 初始化密钥缓存
	 */
	private static void initKeys(Map<String,Key> map,Integer times){
		
		Integer _times = times==null?100:times;
		
		for(int i=0;i<_times;i++){
			
			String strKey = UUID.randomUUID().toString();
			
			SecretKey key = generateKey(strKey);
			
			initMap.put(strKey, key);
		}
	}
	
	/*
	 * 根据基础字符串生成密钥
	 */
	private static SecretKey generateKey(String strKey){
		
		KeyGenerator keygen = null;
		
		SecretKey getKey = null;
		try {
			
			keygen = KeyGenerator.getInstance("AES");
			//初始化密钥  
			keygen.init(new SecureRandom(strKey.getBytes()));
			
			getKey = keygen.generateKey();  
			
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return getKey;
	}
	
	/**
	 * 获取初始密钥
	 * @return
	 */
	public static MDomain getInitKey(){
		
		MDomain m = new MDomain();
		
		//获取密钥代码
		String uuid = UUID.randomUUID().toString();
		
		//获取密钥
		Key key = AESConfig.generateKey(uuid);
		
		byte[] pb = key.getEncoded();
        String pbStr =  new String(Base64.encode(pb));
		m.setC(uuid);
		m.setP(pbStr);
		
		//缓存密钥
		initMap.put(uuid, key);
		return m;
	}
	
	/**
	 * 根据密钥代码在缓存中查找密钥
	 * @param code
	 * @return
	 */
	public static Key getKey(String code){
		
		if( (code != null)  && initMap.containsKey(code)){
			return initMap.get(code);
		}
		return null;
	}
}
